/**
 *
 */
package de.cbf.cam.dsa.item.model.entities.helper;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import de.cbf.util.uuidheader.entities.UUIDHeader;
import de.cbf.util.uuidheader.exceptions.EntityMergeException;

/**
 * @author salter
 * this holds the descriptions for a certain shape with shape levels <br>
 * this could be dirtiness, or fBrokenness
 * index of list is shapeness level
 */
public class Shapeness extends UUIDHeader{
	private static final Log logger = LogFactory.getLog(Shapeness.class);

	public static final int PI_SHAPENESS_DESCRIPTIONS	= 10;
	public static final int PI_SHAPENESS_REASONS		= 11;
	public static final int PI_SHAPENESS_LEVEL_CURRENT	= 12;

	protected List<String> shapenessDescriptions;

	protected List<String> shapenessReasons;

	protected Integer currentLevel;


	public Shapeness() {
		super();
		init();
	}

	protected void init() {
		shapenessDescriptions = new ArrayList<String>();
		shapenessReasons = new ArrayList<String>();
		currentLevel = -1;
	}

	@Override
	protected void doMergeDataFrom(UUIDHeader entity, boolean i_am_older)
			throws EntityMergeException {
		if (entity instanceof Shapeness) {
			Shapeness other = (Shapeness) entity;
			if(i_am_older){
				this.currentLevel = other.currentLevel;
				this.shapenessDescriptions.clear();
				this.shapenessDescriptions.addAll(other.shapenessDescriptions);
				this.shapenessReasons.clear();
				this.shapenessReasons.addAll(other.shapenessReasons);
			}
		}else{
			String mergeEntityClass = entity == null? "null":entity.getClass().getName();
			String errorMsg ="EntityToMerge "+mergeEntityClass+" does not fit class:"+this.getClass().getName();
			throw new EntityMergeException(errorMsg);
		}

	}

	public Integer getLevelOfDescription(String description) {
		return shapenessDescriptions.indexOf(description);
	}

	public void incShapenessLevelBy(Integer inc,List<String> reasons){
		if(currentLevel == -1){
			//not initialized
			logger.error("shapeness not initalized, cannot inc level");
			return;
		}
		//add up current and inc for desired new level
		int newLevel = getCurrentLevel()+inc;
		//correct if desiredNewLevel is over max
		newLevel = newLevel < shapenessDescriptions.size()?newLevel:shapenessDescriptions.size()-1;
		addShapenessReasons(reasons);
	}

	public void decShapenessLevelBy(Integer dec,List<String> reasons){
		if(currentLevel == -1){
			//not initialized
			logger.error("shapeness not initalized, cannot dec level");
			return;
		}
		//add up current and inc for desired new level
		int newLevel = getCurrentLevel()-dec;
		//correct if desiredNewLevel is over max
		newLevel = newLevel >= 0?newLevel:0;
		removeShapenessReasons(reasons);
	}



	public Integer getMaxShapenessLevel(){
		return shapenessDescriptions.size()-1;
	}

	public String getCurrentShapenessDescription(){
		return getShapenessDescriptionForLevel(getCurrentLevel());
	}

	public String getShapenessDescriptionForLevel(Integer level){
		if(currentLevel == -1){
			//not initialized
			logger.error("shapeness not initalized, cannot get current level");
			return "";
		}
		return shapenessDescriptions.get(level);
	}

	public List<String> getShapenessDescriptions() {
		return shapenessDescriptions;
	}

	public void addDescription(String description){
		shapenessDescriptions.add(description);
	}

	public void removeDescription(String description){
		shapenessDescriptions.remove(description);
	}

	public void setDescriptionAt(Integer index, String description) {
		shapenessDescriptions.set(index, description);
	}

	public void frontDescription(String description){
		int indexOld = shapenessDescriptions.indexOf(description);
		if(indexOld <= 0){ //is at front no further up
			return;
		}
		int indexNew = indexOld-1;
		String elementAtNewPos = shapenessDescriptions.get(indexNew);
		shapenessDescriptions.set(indexNew, description);
		shapenessDescriptions.set(indexOld, elementAtNewPos);
	}

	public void backDescription(String description){
		int indexOld = shapenessDescriptions.indexOf(description);
		if(indexOld >= getMaxShapenessLevel()-1){ //is at end no further back
			return;
		}
		int indexNew = indexOld+1;
		String elementAtNewPos = shapenessDescriptions.get(indexNew);
		shapenessDescriptions.set(indexNew, description);
		shapenessDescriptions.set(indexOld, elementAtNewPos);
	}


	public void setShapenessDescriptions(List<String> shapenessDescriptions) {
		if(shapenessDescriptions != null && shapenessDescriptions.size() > 0){
			//if no descriptions present and some were added set current level to 0
			currentLevel = currentLevel == -1? 0:currentLevel;
		}
		this.shapenessDescriptions = shapenessDescriptions;
	}

	public List<String> getShapenessReasons() {
		return shapenessReasons;
	}

	public void addShapenessReasons(List<String> reasons) {
		for (String reason : reasons) {
			if( ! shapenessReasons.contains(reason)){
				shapenessReasons.add(reason);
			}
		}
	}

	public void removeShapenessReasons(List<String> reasons) {
		shapenessReasons.removeAll(reasons);
	}

	public void setShapenessReasons(List<String> shapenessReasons) {
		this.shapenessReasons = shapenessReasons;
	}

	public Integer getCurrentLevel() {
		return currentLevel;
	}

	public void setCurrentLevel(Integer currentLevel) {
		this.currentLevel = currentLevel;
	}




}
